package com.bfly.mall.tasks;

import com.bfly.core.context.event.ScheduledTaskExecCompleteEvent;
import com.bfly.core.security.ScheduledInfo;
import com.bfly.mall.advert.entity.Coupon;
import com.bfly.mall.advert.entity.CouponGetRecord;
import com.bfly.mall.advert.enums.CouponStatus;
import com.bfly.mall.advert.enums.CouponUseStatus;
import com.bfly.mall.advert.service.ICouponService;
import com.bfly.mall.advert.service.ICouponGetRecordService;
import com.bfly.mall.tasks.entity.ScheduledTaskExecResult;
import com.bfly.mall.tasks.service.IScheduled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.*;

/**
 * 优惠卷定时任务
 *
 * @author 长沙商脉科技有限公司
 * @date 2020/11/13 14:54
 */
@Configuration
public class CouponTask extends AbstractScheduledTask implements IScheduled {

    @Autowired
    private ICouponService couponService;
    @Autowired
    private ICouponGetRecordService couponUserService;

    private final String COUPON_STATUS_SETTING = "coupon_status_setting";
    private final String COUPON_FOR_STATUS_CRON = "0 0/10 * * * ?";

    private final String COUPON_USER_STATUS_SETTING = "coupon_user_status_setting";
    private final String COUPON_USER_FOR_STATUS_CRON = "0 0/5 * * * ?";

    /**
     * 定时检查优惠卷活动是否过期设置优惠卷的状态
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/11/13 15:19
     */
    @Scheduled(cron = COUPON_FOR_STATUS_CRON)
    @ScheduledInfo(name = COUPON_STATUS_SETTING, remark = "每10分钟执行一次,检查优惠卷过期状态!")
    public void checkCouponIsExpired() {
        if (!allowRun(COUPON_STATUS_SETTING)) {
            return;
        }
        String message = "执行成功!";
        try {
            Map<String, Object> param = new HashMap<>();
            // 查询活动进行中/未开始/已下架的优惠卷信息
            param.put("status_in", Arrays.asList(CouponStatus.ON_SHELF.getId(),CouponStatus.NOT_START.getId(),CouponStatus.OFF_SHELF.getId()));
            List<Coupon> coupons = couponService.getList(param);
            Date now = new Date();
            if (coupons != null) {
                for (Coupon coupon : coupons) {
                    if (now.after(coupon.getActivityEnd())) {
                        // 活动已经结束 设置活动为已过期
                        couponService.editStatus(coupon.getId(), CouponStatus.EXPIRED);
                    }
                }
            }
        } catch (Exception e) {
            message = e.getMessage();
        }
        ScheduledTaskExecResult result = new ScheduledTaskExecResult(COUPON_STATUS_SETTING, COUPON_FOR_STATUS_CRON, Calendar.getInstance().getTime(), message);
        executeCompletedEvent(new ScheduledTaskExecCompleteEvent(result));
    }

    /**
     * 定时检查用户领取的优惠卷是否过期设置优惠卷的状态
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/11/13 15:19
     */
    @Scheduled(cron = COUPON_USER_FOR_STATUS_CRON)
    @ScheduledInfo(name = COUPON_USER_STATUS_SETTING, remark = "每5分钟执行一次,检查用户优惠卷过期状态!")
    public void checkUserCouponIsExpired() {
        if (!allowRun(COUPON_USER_STATUS_SETTING)) {
            return;
        }
        String message = "执行成功!";
        try {
            Map<String, Object> param = new HashMap<>();
            // 查询未使用状态的优惠卷信息
            param.put("status", CouponUseStatus.NOT_USE.getId());
            List<CouponGetRecord> coupons = couponUserService.getList(param);
            Date now = new Date();
            if (coupons != null) {
                for (CouponGetRecord coupon : coupons) {
                    if (now.after(coupon.getEndDate())) {
                        // 用户优惠卷到期未使用 设置优惠卷为已过期
                        couponUserService.editStatus(coupon.getId(), CouponUseStatus.EXPIRED);
                    }
                }
            }
        } catch (Exception e) {
            message = e.getMessage();
        }
        ScheduledTaskExecResult result = new ScheduledTaskExecResult(COUPON_USER_STATUS_SETTING, COUPON_USER_FOR_STATUS_CRON, Calendar.getInstance().getTime(), message);
        executeCompletedEvent(new ScheduledTaskExecCompleteEvent(result));
    }
}